const imageCache = {};

export const loadImage = (src) => {
    return new Promise((resolve, reject) => {
        if (imageCache[src]) {
            resolve(imageCache[src]);
        } else {
            const img = new Image();
            img.onload = () => {
                imageCache[src] = img;
                resolve(img);
            };
            img.onerror = reject;
            img.crossOrigin = "Anonymous";
            img.src = src;
        }
    });
};
// 获取图片适应屏幕的尺寸
export const getImageAdaptSize = async (
    img,
    { dir, stageWidth, stageHeight }
) => {
    if (dir === "vertical") {
        const height = img.height / (img.width / stageWidth);
        return { width: stageWidth, height };
    } else {
        const width = img.width / (img.height / stageHeight);
        return { width, height: stageHeight };
    }
};

export const addFieldsToMarksArr = (marksArr, fields) => {
    for (let i = 0; i < marksArr.length; i++) {
        const marks = marksArr[i];
        for (const key in fields) {
            addFieldToMarks(marks, key, fields[key]);
        }
    }
};

export const addFieldToMarks = (marks, key, value) => {
    for (let i = 0; i < marks.length; i++) {
        marks[i][key] = value;
    }
};

export const handleMarkFields = (...marksArr) => {
    marksArr.forEach((marks) => {
        // let count = -1;
        marks.forEach((item, index) => {
            item.isHighlight = false;
            item.isEmpty = item.cooridates.length === 0;
            // if (!item.isEmpty) {
            //     count++;
            // item.index = count;
            // }
        });
    });
};

export function capitalizeWord(str) {
    return str.replace(/^\w/g, function (match) {
        return match.toUpperCase();
    });
}

export function transformEssayData(originalData) {
    if (!originalData?.paperInfoVO?.paperImageFileWrapperList) {
        return [];
    }
    return originalData.paperInfoVO.paperImageFileWrapperList.map(
        (imageWrapper) => {
            // 解析 OCR 指针信息
            const ocrPointers = JSON.parse(imageWrapper.ocrPointerInfo || "[]");

            // 转换文字数据
            const words = ocrPointers.map((pointer) => ({
                imageIndex: pointer.imageIndex,
                end: pointer.end,
                lang: pointer.lang,
                pointers: pointer.pointers,
                start: pointer.start,
                word: pointer.word,
            }));

            // 转换选区数据（示例结构，需要根据实际业务逻辑调整）
            const selections = {
                words: [],
                sentences: [],
                paragraphs: [],
            };

            // 这里可以添加更复杂的选区解析逻辑
            // 示例：将第一个文字标记作为示例选区
            // if (words.length > 0) {
            //   selections.words.push({
            //     text: words[0].word,
            //     cooridates: [{
            //       x: words[0].pointers[0],
            //       y: words[0].pointers[1],
            //       x1: words[0].pointers[2],
            //       y1: words[0].pointers[3],
            //       x2: words[0].pointers[4],
            //       y2: words[0].pointers[5],
            //       width: words[0].pointers[6] - words[0].pointers[0],
            //       height: words[0].pointers[7] - words[0].pointers[1]
            //     }]
            //   });
            // }

            return {
                url: imageWrapper.orgImage,
                id: imageWrapper.id.toString(),
                content: imageWrapper.ocrContent,
                words: words,
                selections: selections,
            };
        }
    );
}

export function getSelectedRegions(data, targetText, currentImgIndex) {
    /**
     * 方法一：使用 Unicode 属性转义（推荐现代环境）
     * 特点：同时去除中英文及全角/半角标点
     * 兼容性：需要 ES2018+ 环境（Node.js 10.0+ / 现代浏览器）
     */
    function removePunctuation2(text) {
        // 匹配以下范围：
        // 1. 中文标点：\u3000-\u303F
        // 2. 全角符号：\uFF00-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65
        // 3. 英文标点：!-/:-@[-`{-~
        return text.replace(
            /[\u3000-\u303F\uFF00-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65!-/:-@[-`{-~]/g,
            ""
        );
    }

    // 寻找与目标文本匹配的连续数据对象

    const findMatchingSequence = () => {
        for (let i = 0; i < data.length; i++) {
            let concatenated = "";
            for (let j = i; j < data.length; j++) {
                concatenated += data[j].word;
                if (
                    removePunctuation2(concatenated) ===
                    removePunctuation2(targetText)
                ) {
                    return data.slice(i, j + 1);
                }
                if (concatenated.length > targetText.length) break;
            }
        }
        return null;
    };

    // 将匹配到的对象按换行符分割成多行
    const splitIntoLines = (matchedObjects) => {
        matchedObjects = matchedObjects.filter(
            (item) => item.pointers !== undefined
        );
        const lines = [];
        let currentLine = [];

        for (let i = 0; i < matchedObjects.length; i++) {
            const currentObj = matchedObjects[i];

            if (currentLine.length === 0) {
                // 第一个元素直接加入当前行
                currentLine.push(currentObj);
                continue;
            }

            const prevObj = matchedObjects[i - 1];

            // 获取当前元素的左上角X坐标
            const currentLeftX = currentObj.pointers[0]; // 假设 pointers[0] 是左上角的 X 坐标
            // 获取前一个元素的左上角X坐标
            const prevLeftX = prevObj.pointers[0];

            // 如果当前元素的X坐标小于前一个元素的X坐标，创建新行
            if (currentLeftX < prevLeftX) {
                if (currentLine.length > 0) {
                    lines.push(currentLine);
                }
                currentLine = [currentObj];
            } else {
                currentLine.push(currentObj);
            }
        }

        // 处理最后一行
        if (currentLine.length > 0) {
            lines.push(currentLine);
        }

        return lines;
    };

    // 计算单行的合并区域
    const calculateLineRegion = (lineObjects) => {
        lineObjects = lineObjects.filter((item) => item.pointers !== undefined);
        // console.log(lineObjects);
        if (lineObjects.length === 0) return null;
        let minX = Infinity,
            minY = Infinity,
            maxX = -Infinity,
            maxY = -Infinity;
        for (const obj of lineObjects) {
            const pointers = obj.pointers;
            const xs = [pointers[0], pointers[2], pointers[4], pointers[6]];
            const ys = [pointers[1], pointers[3], pointers[5], pointers[7]];
            minX = Math.min(minX, ...xs);
            minY = Math.min(minY, ...ys);
            maxX = Math.max(maxX, ...xs);
            maxY = Math.max(maxY, ...ys);
        }
        return { x1: minX, y1: minY, x2: maxX, y2: maxY };
    };

    try {
        // 主流程
        const matchedObjects = findMatchingSequence();
        const matchedObjectsFilter = matchedObjects?.filter(
            (item) => item.imageIndex == currentImgIndex
        );

        if (!matchedObjectsFilter) return [];
        const lines = splitIntoLines(matchedObjectsFilter);

        return lines
            .map((line) => calculateLineRegion(line))
            .filter((region) => region !== null);
    } catch (error) {
        return [];
    }
}

// 过滤坐标为空的mark
export function filterEmptyMark(marks) {
    return marks.filter((mark) => {
        return mark.cooridates.length !== 0;
    });
}

export function trimSpecificQuotes(str) {
    if (!str) return str;
    // 同时处理开头的 数字.全角引号 和结尾的全角引号
    return str
        .replace(/^\d+\.\\*["“]/, "") // 处理开头数字.转义符+引号
        .replace(/\\*[”"]$/, ""); // 处理结尾转义符+引号
}

/**
 * 将 Markdown 字符串转换为 HTML
 * @param markdown Markdown 格式的字符串
 * @returns 转换后的 HTML 字符串
 */
export function markdownToHtml(markdown) {
    // 预处理：清理首尾空白和空行
    let html = markdown
        .trim()
        .replace(/\n{3,}/g, "\n\n") // 合并多个空行为两个换行符
        .replace(/^\s*$(?:\n|$)/gm, ""); // 删除所有空行

    // 按处理优先级转换
    html = html
        // 代码块（需优先处理）
        .replace(/```[\s\S]*?```/g, (match) => {
            const code = match.replace(/```/g, "").trim();
            return `<pre><code>${code}</code></pre>`;
        })

        // 标题
        .replace(/^#{1,3} (.*$)/gm, (m, p1) => {
            const level = Math.min(m.match(/#/g)?.length || 1, 3);
            return `<h${level}>${p1}</h${level}>`;
        })

        // 无序列表
        .replace(/^(\* .+$)(\n\* .+$)*/gm, (match) => {
            const items = match
                .split("\n")
                .map((item) => item.replace(/^\* (.*)$/, "<li>$1</li>"))
                .join("");
            return `<ul>${items}</ul>`;
        })

        // 粗体
        .replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")

        // 斜体
        .replace(/\*(.*?)\*/g, "<em>$1</em>")

        // 行内代码
        .replace(/`(.*?)`/g, "<code>$1</code>")

        // 段落处理（最后处理）
        // .replace(
        //     /(^|<\/[^>]+>)\s*([^<\n]+?)\s*(?=$|<\/?[^>]+>)/g,
        //     "$1<p>$2</p>"
        // )

        // 处理换行（非段落分隔的单个换行）
        .replace(/(?<!<\/p>)\n(?!<p>)/g, "<br>");

    return html;
}

export const sleep = (ms) => {
    return new Promise((resolve) => setTimeout(resolve, ms));
};

export const isElementInViewport = (el, viewWidth, viewHeight) => {
    const rect = el.getBoundingClientRect();
    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= viewHeight &&
        rect.right <= viewWidth
    );
};

// 检测是否是点击而不是滑动
export const isClick = (startPos, endPos) => {
    const { x, y } = startPos;
    return x === endPos.x && y === endPos.y;
};
